package oneD.fem.algorithm;

/**
 * interface represent a tensor object. for rank 2 tensor, it's a square matrix
 * while for higher rank tensor it represent by looping over the indices
 * 
 * @author hbui
 * 
 */
public interface ITensor extends Cloneable {

	/**
	 * return the element of the tensor. the dimension of the array input must
	 * be equal to the rank of the tensor
	 * 
	 * @param I
	 * @return the element value
	 */
	double get(int... I);

	/**
	 * 
	 * @return the trace of the tensor
	 */
	double trace();

	/**
	 * 
	 * @return rank of the tensor
	 */
	int rank();

	/**
	 * 
	 * @return the dimension of the tensor
	 */
	int dimension();

	/**
	 * compute the contraction with another tensor
	 * 
	 * @param B
	 * @return new contracted tensor
	 */
	ITensor contraction(ITensor B);

	/**
	 * multiply this tensor with tensor B and return the new tensor. In case of
	 * rank 2, the new tensor is formed by multiplication of 2 matrix
	 * 
	 * @param B
	 * @return new multiplied tensor
	 */
	ITensor multiply(ITensor B);

	/**
	 * implement the operator ":" (both 2 tensors need to be the same rank &
	 * dimension)
	 * 
	 * @param B
	 * @return dot product with tensor B
	 */
	double dot(ITensor B);

	/**
	 * compute dyadic product of 2 tensors
	 * 
	 * @param B
	 * @return new producted tensor
	 */
	ITensor product(ITensor B);

	/**
	 * compute A <- A+alpha*B
	 * 
	 * @param alpha
	 * @param B
	 * @return new tensor
	 */
	ITensor add(double alpha, ITensor B);
}
